﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using ComunesMGI.DataTypes;
using ComunesMGI.Enums;
using ComunesMGI.Constantes;



using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using ComunesMGI.Condiciones;
using ComunesMGI.Excepciones;
using System.ServiceModel;
using System.ServiceModel.Channels;




namespace MGI.AccesoDatos.AccesoSharepoint
{
    class SharepointProxy : ISharepoint
    {

        #region ISharepoint Members

        public string TraducirCampo(string sitio, Lista lista, string campo, string valorCampo, string urlWS)
        {
            String temp;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            temp = sc.TraducirCampo(sitio, lista, campo, valorCampo);
            sc.Close();
            return temp;
        }

        public void EliminarIncidente(string sitio, int incidente, string urlWS)
        {
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            sc.EliminarIncidente(sitio, incidente);
            sc.Close();
        }

        public DataEliminarTarea EliminarTarea(string sitio, int tarea, string urlWS)
        {
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            DataEliminarTarea dataTarea = sc.EliminarTarea(sitio, tarea);
            sc.Close();


            return dataTarea;
        }



        public void DesasociarIncidentesWP(string sitio, List<int> incidentes, string urlWS)
        {

            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            sc.DesasociarIncidentesWP(sitio, incidentes);
            sc.Close();
        }



        public void ModificarIncidente(string sitio, DataIncidenteConCampos incidente, string urlWS)
        {
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            sc.ModificarIncidente(sitio, incidente);
            sc.Close();
        }


        /// <summary>
        /// Dado los títulos de los campos y otra información traida del xml 
        /// de configuración, se retorna una lista con información mas completa 
        /// (incluyendo la anterior) acerca de los campos, traida del sitio 
        /// sharepoint .
        /// </summary>
        /// <param name="cliente"></param>
        /// <param name="sistema"></param>
        /// <param name="tipoLista"></param>
        /// <param name="nomCampos"></param>
        /// <returns>List<DataCampo></returns>
        public List<DataCampo> GetCampos(string sitioSistema, Lista tipoLista, List<DataCampo> nomCampos, string urlWS)
        {

            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            List<DataCampo> campos = sc.GetCampos(sitioSistema, tipoLista, nomCampos);
            sc.Close();
            return campos;


        }





        /// <summary>
        /// Alta de incidente en sharepoint
        /// </summary>
        /// <param name="sistema"></param>
        public DataAltaIncidente AddIncidente(DataSistema sistema)
        {
            string urlWS = sistema.UrlWS;
            DataAltaIncidente resultado;

            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            resultado = sc.AddIncidente(sistema);
            sc.Close();
            return resultado;
        }


        public List<DataIncidente> GetIncidentes(string sitio, List<Condicion> condiciones, string urlWS)
        {
            List<DataIncidente> listaDataIncidente;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            listaDataIncidente = sc.GetIncidentes(sitio, condiciones);
            sc.Close();

            return listaDataIncidente;
        }

        public DataIncidenteConCampos GetIncidente(int idIncidente, string sitio, List<DataCampo> campos, string urlWS)
        {
            DataIncidenteConCampos incidente;

            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            incidente = sc.GetIncidente(idIncidente, sitio, campos);
            sc.Close();

            return incidente;
        }

        public DataEliminarTarea ModificarTarea(string sitio, DataTareaConCampos tarea, string urlWS)
        {
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            DataEliminarTarea det = sc.ModificarTarea(sitio, tarea);
            sc.Close();
            return det;
        }

        public List<DataIncidente> GetIncidentesAsignablesWP(string sitioSistema, int wkpCod, string urlWS, DateTime fechaEstFinWP)
        {
            List<DataIncidente> incidente;

            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            incidente = sc.GetIncidentesAsignablesWP(sitioSistema, wkpCod, fechaEstFinWP);
            sc.Close();

            return incidente;
        }

        /// <summary>
        /// Retorna información de todos los incidentes en el sitio 
        /// del cliente-sistema
        /// </summary>
        /// <param name="cliente"></param>
        /// <param name="sistema"></param>
        /// <returns>List<DataIncidente></returns>
        public List<DataIncidenteReporte> GetIncidentesReporte(DataSistema sistema)
        {
            List<DataIncidenteReporte> incidente;
            string urlWS = sistema.UrlWS;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            incidente = sc.GetIncidentesReporte(sistema);
            sc.Close();

            return incidente;
        }


        /// <summary>
        /// Retorna información de todos los incidentes en el sitio 
        /// del cliente-sistema
        /// </summary>
        /// <param name="cliente"></param>
        /// <param name="sistema"></param>
        /// <returns>List<DataIncidente></returns>
        public List<DataIncidenteReporte> GetIncidentesReporteFiltroUsrEstado(DataSistema sistema, string usuario, string valorCampo, DateTime perFchIni, DateTime perFchFin)
        {
            List<DataIncidenteReporte> incidente;
            string urlWS = sistema.UrlWS;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            incidente = sc.GetIncidentesReporteFiltroUsrEstado(sistema, usuario, valorCampo, perFchIni, perFchFin);
            sc.Close();

            return incidente;
        }





        public List<DataIncidente> GetIncidentesWP(string sitio, int idWorkPackage, string urlWS)
        {
            List<DataIncidente> listaDataIncidente;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            listaDataIncidente = sc.GetIncidentesWP(sitio, idWorkPackage);
            sc.Close();

            return listaDataIncidente;
        }



        /// <summary>
        /// Retorna las tareas en el sitio  
        /// que esten asociadas al incidente indicado
        /// </summary>
        /// <param name="cliente"></param>
        /// <param name="sistema"></param>
        /// <param name="incidente"></param>
        /// <returns>List<DataTarea></returns>
        public List<DataTarea> GetTareas(string sitio, int idIncidente, string urlWS)
        {
            List<DataTarea> listaData;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            listaData = sc.GetTareas(sitio, idIncidente);
            sc.Close();

            return listaData;
        }


        public DataTareaConCampos GetTarea(string sitio, int idTarea, List<DataCampo> campos, string urlWS)
        {
            DataTareaConCampos tarea;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            tarea = sc.GetTarea(sitio, idTarea, campos);
            sc.Close();

            return tarea;
        }


        /// <summary>
        /// Dado un incidente de determinado sistema, una tarea y un usuario,
        /// se asigna la tarea al usuario y se asocia la misma al incidente.
        /// 
        /// </summary>
        /// <param name="sistema"></param>
        /// <param name="incidente"></param>
        /// <param name="tarea"></param>
        /// <param name="usuario"></param>
        /// <returns>
        ///         Retorna la dirección de email del usuario al que se le quiere asignar la tarea
        ///         o si no es válido el mismo, se retorna null
        /// </returns>
        public string AsignarResponsable(string sitioSistema, int idIncidente, int idTarea, DataUsuario usuario, string urlWS)
        {
            string resultado;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            resultado = sc.AsignarResponsable(sitioSistema, idIncidente, idTarea, usuario);
            sc.Close();

            return resultado;
        }


        /// <summary>
        /// Escribe en un archivo temporal la información enviada por el stream.
        /// Es usado para Recibir archivos que posteriormente serán adjuntados a
        /// incidentes en el sharepoint.
        /// </summary>
        /// <param name="sourceStream"></param>
        /// <returns></returns>
        public string UploadFile(Stream sourceStream, string urlWS)
        {
            string resultado;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            resultado = sc.UploadFile(sourceStream);
            sc.Close();

            return resultado;
        }





        /// <summary>
        /// Dada la existencia de un archivo temporal previamente cargado,  
        /// se envía a un sitio sharepoint y se adjunta a un incidente indicado 
        /// con el nombre indicado.
        /// </summary>
        /// <param name="nombreArchivo"></param>
        /// <param name="sistema"></param>
        /// <param name="incidente"></param>
        /// <param name="nroTemp"></param>
        /// <returns>indica si se pudo adjuntar</returns>
        public bool AdjuntarArchivoIncidente(string nombreArchivo, String urlSistema, int idIncidente, string nroTemp, string urlWS)
        {
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);
            bool resultado;
            sc.Open();
            resultado = sc.AdjuntarArchivoIncidente(nombreArchivo, urlSistema, idIncidente, nroTemp);
            sc.Close();

            return resultado;
        }


        public DataAltaTarea AddTarea(string urlSistema, List<DataCampo> campos, string urlWS)
        {
            DataAltaTarea resultado;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            resultado = sc.AddTarea(urlSistema, campos);
            sc.Close();

            return resultado;
        }

        public int GetEsfuerzoTotalWP(string sitio, int idWP, string urlWS)
        {
            int resultado;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            resultado = sc.GetEsfuerzoTotalWP(sitio, idWP);
            sc.Close();

            return resultado;
        }

        public int GetEsfuerzoRestanteWP(string sitio, int idWP, string urlWS)
        {
            int resultado;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            resultado = sc.GetEsfuerzoRestanteWP(sitio, idWP);
            sc.Close();

            return resultado;
        }

        public bool ChkWpIncidentesOTareasSinCerrar(string sitio, int wkpCod, string urlWS)
        {
            bool resultado;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            resultado = sc.ChkWpIncidentesOTareasSinCerrar(sitio, wkpCod);
            sc.Close();

            return resultado;
        }

        public void CerrarAsociadosWP(string sitio, int wpId, string urlWS)
        {
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            sc.CerrarAsociadosWP(sitio, wpId);
            sc.Close();
        }



        /// <summary>
        /// Retorna información de todos los incidentes en el sitio 
        /// del cliente-sistema creados en el período
        /// </summary>
        /// <param name="cliente"></param>
        /// <param name="sistema"></param>
        /// <returns>List<DataIncidente></returns>
        public List<DataIncidenteReporte> GetIncidentesCreadosPeriodo(DataSistema sistema, DateTime perFchIni, DateTime perFchFin)
        {
            List<DataIncidenteReporte> listaDataIncidente;
            string urlWS = sistema.UrlWS;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            listaDataIncidente = sc.GetIncidentesCreadosPeriodo(sistema, perFchIni, perFchFin);
            sc.Close();
            return listaDataIncidente;
        }


        public List<DataSincronizarTarea> GetTareasAsignadasDespuesFecha(string sitio, DateTime fechaSincronizacion, string nombreUsuario, string urlWS)
        {
            List<DataSincronizarTarea> tareas;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            tareas = sc.GetTareasAsignadasDespuesFecha(sitio, fechaSincronizacion, nombreUsuario);
            sc.Close();
            return tareas;
        }


        public void SetIncidenteWP(string sitio, int idWorkPackage, int idIncidente, string urlWS)
        {
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            sc.SetIncidenteWP(sitio, idWorkPackage, idIncidente);
            sc.Close();
        }

        public bool IsFechaEstimadaEntregaWPMayorIncidentes(string sitio, int idWP, DateTime fechaEstEntWP, string urlWS)
        {
            bool resultado;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            resultado = sc.IsFechaEstimadaEntregaWPMayorIncidentes(sitio, idWP, fechaEstEntWP);
            sc.Close();

            return resultado;
        }

        public void ChkUrlWS(string urlWS)
        {
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);
            sc.Open();
            sc.Close();
        }

        public void ChkSitioSistema(string sitio, string urlWS) 
        {
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);
            sc.Open();
            sc.ChkSitioSistema(sitio);
            sc.Close();
        }

        public List<string> GetEstadosIncidentes(string sitio, string urlWS) 
        {
            List<string> resultado = null;
            EndpointAddress sa = new EndpointAddress(urlWS);
            Binding bind = new BasicHttpBinding();
            SharepointWS.SharepointClient sc = new SharepointWS.SharepointClient(bind, sa);

            sc.Open();
            resultado = sc.GetEstadosIncidentes( sitio);
            sc.Close();

            return resultado;
        }


        #endregion





        /// <summary>
        /// Mapea los tipos de campos de sharepoint a los de MGI
        /// </summary>
        /// <param name="spType">String representando el tipo de datos de sharepoint</param>
        /// <returns></returns>
        public static CampoSharepoint spTypeToCampoSharepoint(string spType)
        {
            switch (spType)
            {
                case "Choice":
                    return CampoSharepoint.Choice;
                case "DateTime":
                    return CampoSharepoint.DateTime;
                case "Number":
                    return CampoSharepoint.Number;
                case "Text":
                    return CampoSharepoint.Text;
                case "Boolean":
                    return CampoSharepoint.Boolean;
                case "Note":
                    return CampoSharepoint.Note;
                case "User":
                    return CampoSharepoint.User;
                default:
                    throw new NotImplementedException("Tipo de Sharepoint no soportado");
            }
        }
    }
}
